package com.loie.xcx.util;

import com.loie.xcx.comm.CustomException;
import com.loie.xcx.comm.SeqEnum;
import lombok.AllArgsConstructor;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author zhl
 */
@Component
@AllArgsConstructor
public class SeqUtil {
    private RedisTemplate<String, String> redisTemplate;
    private Environment environment;

    public String getSeq(SeqEnum prefix, String dateFormat, int num) {
        String key = String.format("xcxAPI:sequence:%s", prefix.toString());
        FileChannel channel = null;
        try {
            synchronized (this) {
                Long inc = redisTemplate.opsForValue().increment(key, 1);
                if (inc != null) {
                    if (inc == 1) {
                        Calendar c = Calendar.getInstance();
                        c.set(Calendar.HOUR_OF_DAY, 0);
                        c.set(Calendar.MINUTE, 0);
                        c.set(Calendar.SECOND, 0);
                        c.set(Calendar.MILLISECOND, 0);
                        c.add(Calendar.DAY_OF_MONTH, +1);
                        long tomorrow = c.getTimeInMillis();
                        Date date = new Date(tomorrow);
                        redisTemplate.expireAt(key, date);
                    }
                    File file = new File(environment.getProperty("seq.path") + "/" + prefix + ".txt");
                    channel = new FileOutputStream(file).getChannel();
                    channel.write(ByteBuffer.wrap(inc.toString().getBytes()));

                    return String.format("%s%s%0" + num + "d", prefix, new SimpleDateFormat(dateFormat).format(new Date()), inc);
                } else {
                    throw new CustomException(400, "取序号异常");
                }
            }
        } catch (IOException e) {
            throw new CustomException(400, "取序号异常");
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
